use queue::Queue;
use stack::Stack;

fn stack_init() -> Stack<i32> {
    let mut s = Stack::new();
    s.push(1);
    s.push(2);
    s.push(3);
    s
}
fn queue_init() -> Queue<i32> {
    let mut queue = Queue::new(4);
    let _ = queue.enqueue(1);
    let _ = queue.enqueue(2);
    let _ = queue.enqueue(3);
    let _ = queue.enqueue(4);
    queue
}

fn main() {
    let s = stack_init();
    stack_basic(s.clone());
    stack_peek(s.clone());
    stack_iter(s.clone());
    let q = queue_init();
    queue_basic(q.clone());
    queue_iter(q.clone());
}

fn stack_basic(mut s: Stack<i32>) {
    println!("size: {},{:?}", s.len(), s);
    println!("pop: {:?},size {}", s.pop().unwrap(), s.len());
    println!("empty: {},{:?}", s.is_empty(), s);
}

fn stack_peek(mut s: Stack<i32>) {
    println!("{:?}", s);
    let peek_mut = s.peek_mut();
    if let Some(top) = peek_mut {
        *top = 4;
    }
    println!("top {:?}", s.peek().unwrap());
    println!("{:?}", s);
}

fn stack_iter(mut s: Stack<i32>) {
    let sum1 = s.iter().sum::<i32>();
    let mut added = 0;
    for item in s.iter_mut() {
        *item += 1;
        added += 1;
    }
    let sum2 = s.iter().sum::<i32>();
    println!("{sum1} + {added} = {sum2}");
    assert_eq!(9, s.into_iter().sum());
}

fn queue_basic(mut q: Queue<i32>) {
    if let Err(error) = q.enqueue(5) {
        println!("Enqueue error:{error}");
    }
    if let Some(data) = q.dequeue() {
        println!("dequeue data: {data}");
    } else {
        println!("empty queue");
    }
    println!("empty:{},len:{}", q.is_empty(), q.len());
    println!("full: {}", q.is_full());
    println!("q: {:?}", q);
    println!("{:?}", q);
}

fn queue_iter(mut q: Queue<i32>) {
    let sum1 = q.iter().sum::<i32>();
    let mut addend = 0;
    for item in q.iter_mut() {
        *item += 1;
        addend += 1;
    }
    let sum2 = q.iter().sum::<i32>();
    println!("{sum1} + {addend} = {sum2}");
    println!("sum = {}", q.into_iter().sum::<i32>());
}
